/**
 * 与业务相关的公共代码都写在这里
 * zhaohuihua, 2016-10-29
 */

// 拦截全局错误
+function(window, Config) {
	window.onerror = function(msg, url, line) {
		if (Config.hybrid && Config.debug) {
			alert("Error: " + msg + "\nURL: " + url + "\nLine: " + line);
		}
		return false; // 返回值为false则仍然输出到控制台
	};
}(window, window.Config || {});

// Utils工具类
+function($) {
	var VIEW_REGEXP = /\b((app_\w+|mui_\w+|aaaa\w+|assets)\/)/;

	var toast = function(message) {
		if (Config.hybrid || !window.top.mui) {
			Utils.app.showToast(message);
		} else {
			window.top.mui.toast(message);
		}
	};

	var concatUrl = function(base, uri) {
		if (!base.endsWith('/')) { base += '/'; }
		if (uri == undefined) {
			return base;
		} else if (/^https?:/.test(uri) || uri.charAt(0) == '/') {
			return uri;
		} else {
			return base + uri;
		}
	};
	var getBaseUrl = function(uri) {
		var url = window.location.href;
		var matcher = /^(https?:\/\/[^\/]+\/)/.exec(url);
		return concatUrl(matcher[1], uri);
	};
	var getViewUrl = function(url, uri) {
		if (!uri) {
			uri = url; url = window.location.href;
		}
		url = url.replace(/[\?\#].*/, "");
		var matcher = VIEW_REGEXP.exec(url);
		if (!matcher) {
			return concatUrl(window.Config.baseUrl, uri);
		}
		var base = url.substring(0, matcher.index);
		if (uri && !/^https?:/.test(uri) && !VIEW_REGEXP.test(uri)) { uri = matcher[1] + uri; }
		return concatUrl(base, uri);
	};
	// getViewData("index.html");
	// getViewData("http://xxx.com/app_yyy/index.html");
	var getViewData = function(url) {
		if (!url) { url = window.location.href; }
		url = url.replace(/[\?\#].*/, "");
		var matcher = VIEW_REGEXP.exec(url);
		if (!matcher) {
			url = getViewUrl(url);
			matcher = VIEW_REGEXP.exec(url);
		}
		return { root:matcher[1].replace("/", ""), page:url.substring(matcher.index + matcher[1].length) };
	};

	var setCacheItem = function(key, object) {
		if (object == undefined) {
			window.localStorage.removeItem(key);
		} else {
			// 如果不是对象, 则保存为{$:xxx}, 以便能正确还原数据类型
			// TODO Date类型还不能正确还原
			if (!$.isPlainObject(object) && !$.isArray(object)) {
				object = {$:object};
			}
			window.localStorage.setItem(key, JSON.stringify(object));
		}
	};
	var getCacheItem = function(key, parse) {
		var string = window.localStorage.getItem(key);
		if (!string) { return null; }
		if (parse === false) {
			return string;
		} else {
			if (string.startsWith('[')) {
				return JSON.parse(string);
			} else if (string.startsWith('{')) {
				// 如果是{$:xxx}格式, 则取json.$以便还原数据类型
				var json = JSON.parse(string);
				if ("$" in json) {
					var count = 0;
					for (var k in json) { count ++; }
					if (count == 1) { return json.$; }
					else { return json; }
				} else {
					return json;
				}
			} else {
				return string;
			}
		}
	};
	var delCacheItem = function(key, parse) {
		var old = getCacheItem(key, parse);
		window.localStorage.removeItem(key);
		return old;
	};

	// 生成随机序列号
	var generateRandomCode = function(workCode) {
		var time = Dates.format(new Date(), "yyMMddhhmmssSSS");
		return time + Randoms.number(6) + (workCode ? workCode : "");
	};

	var openWindow = function(replace, url, hashParams, passParams) {
		if (passParams) {
			// 参数发送至子页面
			sendPassParams(url, passParams);
		}
		var options = {};
		if (typeof(url) == "string") {
			options.url = url;
		} else {
			options = url;
		}
		if (!options.id) {
			var index = options.url.lastIndexOf('.');
			if (index > 0) {
				options.id = options.url.substring(0, index);
			}
		}
		if (Config.xview) {
			if (replace) {
				Config.xview.replace(url, hashParams);
			} else {
				Config.xview.go(url, hashParams);
			}
		} else {
			if (hashParams) {
				options.url += "#" + $.param(hashParams);
			}
			if (replace) {
				window.top.location.replace(options.url);
			} else {
				mui.openWindow(options);
			}
		}
	};
	// 页面间传递参数
	var sendPassParams = function(url, json) {
		var vd = getViewData(url);
		var passid = "PassParams." + vd.root + "." + vd.page;
		setCacheItem(passid, json);
	};
	// 接收传递的参数
	var getPassParams = function() {
		if (!window.PassParams) {
			var vd = getViewData();
			var passid = "PassParams." + vd.root + "." + vd.page;
			window.PassParams = delCacheItem(passid) || {};
		}
		return window.PassParams;
	};
	if (window != window.top) {
		getPassParams(); // 立即接收参数, 只有子页面执行
	}

	if (!window.Utils) { window.Utils = {}; }
	var ua = window.navigator.userAgent;
	$.extend(window.Utils, {
		// https://github.com/faisalman/ua-parser-js/blob/master/src/ua-parser.js
		ios: !!/(ip[honead]+)(?:.*os\s([\w]+)*\slike\smac|;\sopera)/i.exec(ua),
		android: !!/android/i.exec(ua),
		// 事件
		events: window.top.$.zhh.events,
		/**
		 * 显示消息提示框
		 * @param message 消息提示文本
		 */
		toast: toast,
		/**
		 * @description 获取接口地址
		 * @example
		 * Utils.getBaseUrl('zhrws/ZHRWS2117');
		 */
		getBaseUrl:getBaseUrl,
		/**
		 * @description 获取页面地址
		 * @example
		 * Utils.getViewUrl('app_Main/html/setting.html');
		 */
		getViewUrl:getViewUrl,
		/**
		 * 如果字段为空，接口会返回{}，此时需要改为空字符串
		 */
		getString: function(string) {
			if (string == undefined) { return ""; }
			if (string == "[object Object]" || string == "undefined") { return ""; }
			if ($.isPlainObject(string)) { return ""; }
			return string.toString();
		},
		/**
		 * @description 获取数组
		 * @example
		 * Utils.getArray(undefined);  =  []
		 * Utils.getArray({});  =  []
		 * Utils.getArray({xx:value});  =  [{xx:value}]
		 */
		getArray:function(array) {
			if (array == undefined) { return []; }
			if ($.isArray(array)) { return array; }
			if ($.isPlainObject(array) && $.isEmptyObject(array)) { return []; }
			return [array];
		},
		/**
		 * 滚动至指定位置
		 * Utils.muiScrollTo(0);
		 * Utils.muiScrollTo("top");
		 * Utils.muiScrollTo("bottom");
		 * Utils.muiScrollTo($elem);
		 */
		muiScrollTo: function(target, time, easing) {
			var api = mui(".mui-scroll-wrapper").scroll();
			if (!api.reLayout || !api.scrollTo) { return; } // 没有滚动条
			api.reLayout();
			var y;
			if ($.dt.isNumeric(target)) {
				y = target * 1;
			} else if (target == "top") {
				y = 0;
			} else if (target == "bottom") {
				y = api.maxScrollY;
			} else if ($.dt.isElement(target)) {
				y = api.y - $(target).offset().top + $("header").height() + 10;
			} else {
				return;
			}
			var time = time || api.options.scrollTime;
			api.scrollTo(api.x, y, time, easing);
		},
		/**
		 * Utils.generateRandomCode(workCode:string);
		 * @description 生成随机序列号
		 * @param workCode 当前登录工号
		 */
		generateRandomCode:generateRandomCode,
		/**
		 * 向下一页面传递参数
		 * Utils.sendPassParams(json);
		 */
		sendPassParams:sendPassParams,
		/**
		 * 接收上一页面传递的参数
		 * Utils.getPassParams();
		 * @return json
		 */
		getPassParams:getPassParams,
		nav: {
			/**
			 * 返回
			 * Utils.nav.back(); // 返回上一页
			 * 返回至某页面, 仅在xview模式下有效
			 * Utils.nav.back('list.html'); // 返回至指定页面
			 * Utils.nav.back(-n); // 返回至上n个页面
			 * Utils.nav.back(+n); // 返回至第n个页面
			 */
			back: function(page) {
				mui.back(page); // 不用判断xview了, 如果是xview模式, mui.back已经被重新定义了
			},
			/**
			 * 重新加载
			 * Utils.nav.reload()
			 */
			reload: function() {
				if (Config.xview) {
					var iframe = Config.xview.subwindow();
					iframe && iframe.location.reload();
				} else {
					window.top.location.reload();
				}
			},
			/**
			 * 跳转至下一页
			 * Utils.nav.next(url:string, hashParams:json, passParams:json);
			 */
			next: function(url, hashParams, passParams) {
				return openWindow(false, url, hashParams, passParams);
			},
			/**
			 * 替换当前页
			 * Utils.nav.replace(url:string, hashParams:json, passParams:json);
			 */
			replace: function(url, hashParams, passParams) {
				return openWindow(true, url, hashParams, passParams);
			},
			/**
			 * 获取缓存的页面
			 * var iframe = Utils.nav.view('list.html');
			 * var xxx = $(iframe.document.body).find("xxx");
			 * Utils.nav.view(-n); == 上n个页面
			 * Utils.nav.view(+n); == 第n个页面
			 */
			view: function(name) {
				if (Config.xview) {
					return Config.xview.subwindow.apply(Config.xview, arguments);
				}
			},
			/**
			 * 执行缓存页面的方法
			 * Utils.nav.invoke('list.html', method, argument 1, ..., argument n);
			 * Utils.nav.invoke(-n, method, argument 1, ..., argument n); // 执行上n个页面的方法
			 * Utils.nav.invoke(+n, method, argument 1, ..., argument n); // 执行第n个页面的方法
			 */
			invoke: function(page, method) {
				if (Config.xview) {
					return Config.xview.invoke.apply(Config.xview, arguments);
				}
			}
		},
		cache: {
			/**
			 * Utils.cache.set(key:string, object:string|json);
			 * @description 将对象保存至缓存
			 * @example
			 * Utils.cache.set('USER_INFO', { id:10001, name:'xxx' });
			 */
			set:setCacheItem, 
			/**
			 * Utils.cache.get(key:string)
			 * Utils.cache.get(key:string, parse:true|false)
			 * @description 从缓存中读取对象
			 * @param parse 是否解析为对象, 默认为true
			 * @example
			 * Utils.cache.get('USER_INFO'); = { id:10001, name:'xxx' }
			 */
			get:getCacheItem,
			/**
			 * Utils.cache.del(key:string);
			 * Utils.cache.del(key:string, parse:true|false);
			 * @description 从缓存中删除对象
			 * @param parse 是否解析为对象, 默认为true
			 * @return 返回被删除的对象
			 * @example
			 * Utils.cache.del('USER_INFO');
			 */
			del:delCacheItem
		}
	});

}(jQuery);


//+function($) {
//	if (Config.xview && window != window.top) {
//		mui.back = window.top.mui.back;
//	}
//
//	// debug模式下双击标题栏刷新缓存
//	if (Config.debug && window.applicationCache && window.applicationCache.update) {
//		$(document.body).on("doubletap", "header", function() {
//			try {
//				Utils.toast("正在刷新缓存...");
//				window.applicationCache.update();
//				setTimeout(function() {
//					window.location.reload();
//				}, 500);
//			} catch (e) {
//				Utils.toast("刷新缓存失败...");
//			}
//		});
//	}
//
//	// 右上角菜单点击事件
//	$(document.body).on("tap", "header [data-open-popover], footer [data-open-popover]", function() {
//		var me = $(this);
//		var zo = me.zoptions("open-popover");
//		if (zo == true) { zo = {target:".mui-popover"}; }
//		me.closest("header, footer").find(zo.target).popover("show", this, zo.follow, zo.cls);
//	});
//
//	// 针对ios和安卓的BUG分别处理, zhaohuihua, 2016-12-23
//	if (Utils.ios) {
//		// 针对ios处于文本框编辑状态时点击页面任意位置无法收回键盘的问题, 调用原生方法处理
//		$(document.body).on("tap", "*", function() {
//			if (window.top.webview && window.top.webview.closeKeyboard) {
//				window.top.webview.closeKeyboard();
//			}
//		});
//		if (window.mui) {
//			// ios, 超快速点击输入框时, 输入框不能获得焦点, 不知道为什么
//			$(document.body).on("tap", "input, textarea", function() {
//				var self = this;
//				var me = $(self);
//				if (me.prop("readonly") == false && self != document.activeElement) {
//					setTimeout(function() {
//						if (self != document.activeElement) {
//							me.focus();
//						}
//					}, 100);
//				}
//			});
//		}
//	}
//	if (Utils.android && window.mui) {
//		// 安卓, 输入框会被弹出的键盘挡住
//		// 不能用focus, 因为当键盘弹出后手动关闭键盘时焦点仍在输入框, 再点该输入框打开键盘, 不会触发focus
//		$(document.body).on("tap", "input, textarea", function() {
//			var me = $(this);
//			// 非只读且在mui-scroll-wrapper之中的才滚动
//			if (me.prop("readonly") == false && me.closest(".mui-scroll-wrapper").length) {
//				setTimeout(function() { Utils.muiScrollTo(me); }, 500);
//			}
//		});
//	}
//}(jQuery);

+function($) {
	// 清除输入框时触发change事件
	$(document).on("tap", ".mui-icon-clear", function() {
		var me = $(this);
		me.prevAll("input").change();
	});
}(jQuery);

+function($, Config) {
	if (window == window.top) {
		// debug模式, 只有在内网和dev环境为true
		Config.debug = /^https?\:\/\/(localhost|127\.|10\.|192\.168\.|\w*test\.|\w*dev\.)/.test(location.href);
		// 是混合应用还是浏览器环境, 该配置项在WebView调用initaccount()方法时Utils.cache.set("ConfigHybrid", true);
		Config.hybrid = Utils.cache.get("ConfigHybrid");
	}
}(jQuery, window.Config || {});

+function(Utils) {
	Utils.formSubmit = function(form, params, fn) {
		if ($.isFunction(params)) { fn = params; params = undefined; }
		var method = form.attr("method");
		var url = form.attr("action");
		var pp = $.getPageParams();
		var data = $.extend({}, pp, form.serializeJson(), params);
		form.zajax(url, data, {
			succ: function(json) {
				form.find(".prompt-message").text("");
				fn && fn.call(form, json);
			},
			failTips: function(json) { // 登录失败, 显示提示消息
				form.find(".prompt-message").text(json && json.message || "网络异常, 请稍候重试");
			}
		});
	};
	Utils.formValidAndSubmit = function(form, params, fn) {
		if ($.isFunction(params)) { fn = params; params = undefined; }
		form.zhhvalidate({ tips:false }, function(e) {
	        if (e.passed) { // 校验通过, 提交
				form.find(".prompt-message").text("");
				Utils.formSubmit(form, params, fn);
	        } else { // 校验不通过, 显示错误提示
				form.find(".prompt-message").text(e.text);
	        }
	    });
	};
}(window.Utils);


/**
 * -------------------------------------------------------------
 * 照片附件插件
 * -------------------------------------------------------------
	<div class="ln uploads do-camera" data-options="limitCount:5, imageName:'imageInfos[i].imagePath'">
		<a class="camera"></a>
	</div>
	$(".do-camera").on("change", function(e, json) {
		// json = { total:number, url:string, index:integer } // 新增时有url, 删除时有index
	});
 * -------------------------------------------------------------
	<div class="ln uploads edit-camera" data-options="imageName:'imageInfos[i].imagePath'">
		<a class="camera"></a>
	</div>
	$(".edit-camera").zcamera({
		on: {
			// json = { url:string }
			add: function(api, json) { if (...) { api.add(json); } },
			// json = { index:integer }
			del: function(api, json) { if (...) { api.del(json); } }
		}
	});
 * -------------------------------------------------------------
 */
+function($) {
	"use strict"

	var API_KEY = 'zloading';
	$.fn.zcamera = function(options) {
		if (options === 'api') {
			return init.call(this[0]);
		} else if (typeof(options) == 'string' && Camera.prototype[options]) {
			var api = init.call(this[0]);
			return api[options].apply(api, Array.prototype.splice.call(arguments, 1));
		}

		return this.each(function() {
			init.call(this, options);
		});
	};
	
	var init = function(options) {
		var me = $(this);
		var api = me.data(API_KEY);
		if (!api) {
			$(this).data(API_KEY, api = new Camera(this, options));
		}
		return api;
	};

	// 构造函数
	var Camera = function(element, options) {
		this.$element = $(element);
	    this.options = $.extend(true, { }, $.fn.zcamera.defaults, this.$element.zoptions(), options);
	    this.init();
	};
	// 初始化
	Camera.prototype.init = function() {
		var api = this;
		var me = api.$element;
		var o = api.options;
		if (me.find(o.selector.add).length == 0) {
			me.append(o.template.camera);
		}
		me.off("tap.zcamera");
		me.on("tap.zcamera", o.selector.add, function() {
			o.allCount = 0;
			var total = me.find("a.image").length;
			var params = { limitCount:o.limitCount, currCount:total };
			Utils.app.uploadFileBase64(params, function( json ){ //{base64:, num
				// 获取图像的Base64数据，需要用户选择相册、相机
				// 如果选中了多张, 会多次回调
				if ( json.base64 ) {
					var url = "data:image/jpg;base64," + json.base64;
					o.on.add.call(this, api, { url:url,num:json.num });
				}
			});
		});
		me.on("tap.zcamera", o.selector.del, function() {
			var $image = $(this).closest(o.selector.image);
			var index = me.find(o.selector.image).index($image[0]);
			o.on.del.call(this, api, { index:index, $image:$image });
		});
	};
	Camera.prototype.clear = function() {
		var api = this;
		var me = api.$element;
		var o = api.options;
		me.find(o.selector.image).remove();
	};
	/**
	 * 增加图片
		json = { 
			url:string, // 图片地址, 填写在<img src="{url}">中
			originalUrl:string, // 原图片地址, 用于预览时查看的大图
			deletable:boolean, // 是否可删除, 默认可删除
			uploadable: boolean, // 是否可上传, 默认可上传
			extra:json, // 其他附加属性, <a class="image" data-extra="{extra}">
			num:int //图片总张数
		}
	 */ 
	Camera.prototype.add = function(json) {
		if ($.dt.isString(json)) { json = { url:json }; }
		var api = this;
		var me = api.$element;
		var o = api.options;
		var tpl = baidu.template(o.template.image);
		var html = tpl($.extend(true, { imageName:o.imageName, imageGroup:o.imageGroup }, json));
		var $image = $(html);
		me.append($image);
		me.trigger("change", $.extend(true, { total:me.find("a.image").length }, json));
		return $image;
	};
	Camera.prototype.del = function(json) { // json = { index:integer }
		var api = this;
		var me = api.$element;
		var o = api.options;
		me.find(o.selector.image).eq(json.index).remove();
		me.trigger("change", $.extend(true, { total:me.find("a.image").length }, json));
	};
	
	$.fn.zcamera.defaults = {
		limitCount: 5, // 总共允许选择几张照片
		allCount: 0,
		imageName:"images", // 图片名称
		imageGroup:"images", // 预览图片的分组
		selector:{ image:".image", add:".camera", del:".delete" },
		template:{
			camera:'<a class="camera"></a>',
			image:
				'<a class="image" data-extra="<#:h=JSON.stringify(this.extra)#>">' + 
				'	<img src="<#=this.url#>" <#if(this.uploadable!=false){#>data-zupload="<#=this.imageName#>"<#}#> data-preview-src="<#=this.originalUrl#>" data-preview-group="<#=this.imageGroup#>" />'+
				'	<#if(this.deletable!=false){#><i class="delete"></i><#}#>' + 
				'</a>'
		},
		on: {
			// json = { url:string }
			add: function(api, json) { api.add(json); },
			// json = { index:integer }
			del: function(api, json) { api.del(json); }
		}
	};
}(jQuery);

